package com.lvt.design.pattern.module.stat.v1;

import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static java.util.Collections.max;

/**
 * @author LT
 * @date 2023年02月22日 22:09
 */
public class Metrics {
    private Map<String, List<Double>> responseTimes = new HashMap<>();
    private Map<String, List<Double>> timestamps = new HashMap<>();
    private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    /**
     * 记录接口的响应时间
     *
     * @param apiName
     * @param responseTime
     */
    public void recordResponseTime(String apiName, double responseTime) {
        responseTimes.putIfAbsent(apiName, new ArrayList<>());
        responseTimes.get(apiName).add(responseTime);
    }

    /**
     * 记录接口的访问时间
     *
     * @param apiName
     * @param timestamp
     */
    public void recordTimestamp(String apiName, double timestamp) {
       timestamps.putIfAbsent(apiName, new ArrayList<>());
       timestamps.get(apiName).add(timestamp);
    }

    /**
     * 指定频率统计数据并输出结果
     *
     * @param period
     * @param unit
     */
    public void startRepeatedReport(long period, TimeUnit unit) {
       executorService.scheduleAtFixedRate(new Runnable() {
           @Override
           public void run() {
               Gson gson = new Gson();
               Map<String, Map<String, Double>> stats = new HashMap<>();
               for (Map.Entry<String, List<Double>> entry : responseTimes.entrySet()) {
                   String apiName = entry.getKey();
                   List<Double> apiRespTimes = entry.getValue();
                   stats.putIfAbsent(apiName, new HashMap<>());
                   stats.get(apiName).put("max", max(apiRespTimes));
                   stats.get(apiName).put("avg", apiRespTimes.stream().mapToDouble(Double::doubleValue).average().getAsDouble());
               }

               for (Map.Entry<String, List<Double>> entry : timestamps.entrySet()) {
                   String apiName = entry.getKey();
                   List<Double> apiTimestamps = entry.getValue();
                   stats.putIfAbsent(apiName, new HashMap<>());
                   stats.get(apiName).put("count", (double)apiTimestamps.size());
               }
               // 输出结果到Console
               System.out.println(gson.toJson(stats));
           }
       }, 0, period, unit);
    }
}
